package com.heqiang.utils;

import com.alibaba.fastjson.JSONObject;
import com.heqiang.constant.Constant;
import org.apache.commons.lang3.StringUtils;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 文件上传
 * 
 * @author felix
 * @date 2015-6-9 下午6:12:12
 */
@Component
public class UploadHelper {

	private static Logger logger = LoggerFactory.getLogger(com.heqiang.utils.UploadHelper.class);
	
	/**
	 * 保存单个文件都本地
	 * @param request
	 * @param file
	 * @return
	 * @throws IOException
	 */
	public JSONObject saveSingleFile(HttpServletRequest request, MultipartFile file, int sizeLimit) throws IOException {
		JSONObject jobject = new JSONObject();
		String saveName = UUID.randomUUID().toString();
		if (null == file) {
			jobject.put("success",false);
			jobject.put("info", "文件为空");
			return jobject;
		}
		if (file.getSize() > sizeLimit){
			jobject.put("success",false);
			jobject.put("info", "文件大小超过限制");
			return jobject;
		}
		String oriName = file.getOriginalFilename().trim();
		String suffix = oriName.substring(oriName.lastIndexOf(".") + 1);
		if ("blob".equals(suffix)){
			suffix = "png";
		}
		saveName = saveName + "." + suffix;
		//上传到阿里云
		OssUtils.uploadFile(file, saveName);
		//返回一个url（ueditor上传时需要返回这个参数）
		String url = OssUtils.IMG_URL + "/" + saveName;
		jobject.put("url", url);
		//返回结构
		jobject.put("success", true);
		jobject.put("saveName", saveName);
		jobject.put("desc", "文件成功上传");
        jobject.put("state", "SUCCESS");
		return jobject;
	}
	
	
	/**
	 * 保存单个文件到本地
	 * @param request
	 * @param file
	 * @return
	 * @throws IOException
	 */
	public JSONObject saveLocalSingleFile(HttpServletRequest request, MultipartFile file, int sizeLimit) throws IOException {
		JSONObject jobject = new JSONObject();
		String saveName = "";
		if (file == null) {
			jobject.put("success",false);
			jobject.put("info", "文件为空");
			return jobject;
		}
		if(file.getSize() > sizeLimit){
			jobject.put("success",false);
			jobject.put("info", "文件大小超过限制");
			return jobject;
		}
		String oriName = file.getOriginalFilename().trim();
		String suffix = oriName.substring(oriName.lastIndexOf(".") + 1);
		if("blob".equals(suffix)){
			suffix = "png";
		}
		saveName = StringUtils.isEmpty(saveName) ? UUID.randomUUID().toString() : saveName;
		saveName = saveName + "." + suffix;
		//上传临时存放
		String floder = Constant.FILE_PATH.LOCAL_EXCEL;
		//上传本地
		//String floder = request.getSession().getServletContext().getRealPath("/resources/file");
		FileUtils.copyInputStreamToFile(file.getInputStream(), new File(floder, saveName));
		String url = floder + "/" + saveName;
		jobject.put("url", url);
		//返回结构
		jobject.put("success",true);
		jobject.put("saveName", saveName);
		jobject.put("desc", "文件成功上传");
        jobject.put("state", "SUCCESS");
		return jobject;
	}

	public JSONObject saveSingleUpload(String fileNamePrefix, HttpServletRequest request,
									   int maxFileSize, long fileAvailableTime, Map<String, String> params, String folder) throws Exception {
		// String path = request.getSession().getServletContext().getRealPath("/resources/uploads");
		JSONObject jsonObj = new JSONObject();
		String path = request.getSession().getServletContext().getRealPath("" + folder);
		List<FileItem> fileItems = null;
		try {
			//如果目录不存在，则创建一个新的目录
			File dir = new File(path);
			if (!dir.exists()) {
				dir.mkdirs();
			}

			fileItems = handleFormUpload(request, maxFileSize, params);
			if (fileItems.size() <= 0) {
				throw new Exception("空文件列表.");
			}
			// 单个上传
			FileItem item = fileItems.get(0);
			String fileName = item.getName();
			String suffix = "";
			// 某些版本浏览器上传文件时，http报文中的文件名称是全路径，会提示文件名不合法
			if (fileName.indexOf("\\") >= 0) {
				fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
			}
			fileName = fileName.trim();

			// 得到文件后缀
			if (fileName.indexOf(".") >= 0) {
				suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
			}
			suffix = fileName.substring(fileName.lastIndexOf(".") + 1);

			if (item.getSize() <= 0) {
				throw new Exception("空文件.");
			}

			String saveFileName = fileNamePrefix + UUID.randomUUID().toString() + "."
					+ suffix;
			item.write(new File(path, saveFileName));// 执行上传....
			if(item.getSize() > 1024 * 1024){
				logger.info("文件大小为：" + item.getSize() / 1024 / 1024 + "MB");
			}else{
				logger.info("文件大小为：" + item.getSize() / 1024 + "KB");
			}
			long fileSize = item.getSize() / 1024;
			jsonObj.put("size",fileSize); // 单位：KB
			jsonObj.put("success", true);
			jsonObj.put("saveName", saveFileName);
			jsonObj.put("originalName",fileName);
		}
		catch (Exception e) {
			logger.error("上传文件失败,msg:"+e.getMessage(), e);
			throw new Exception("上传文件失败", e);
		}
		finally {
			if (fileItems != null) {
				for (FileItem item : fileItems) {
					item.delete();
				}
			}
		}
		return jsonObj;
	}

	/**
	 *
	 * 保存multipart/form-data类型的表单中提交的文件， 并以key，value的格式返回从表单中解析出的参数
	 *
	 * @author kmchen
	 * @param request
	 * @param maxSize request最大长度
	 * @param maxFileSize 文件大小限制
	 * @param params 保存表单中解析出的参数
	 * @return 从表单中解析出的文件
	 * @throws Exception
	 */
	private List<FileItem> handleFormUpload(HttpServletRequest request, int maxFileSize,
                                            Map<String, String> params) throws Exception {

		DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(fileItemFactory);

		fileItemFactory.setSizeThreshold(1024);
		upload.setFileSizeMax(maxFileSize);
		List<FileItem> FileItems = null;
		try {
			@SuppressWarnings("rawtypes")
			List fileItems = upload.parseRequest(request);
			FileItems = new ArrayList<FileItem>();
			for (int i = 0; i < fileItems.size(); i++) {
				FileItem item = (FileItem) fileItems.get(i);
				if (!item.isFormField()) {
					FileItems.add(item);
				}
				else {
					params.put(item.getFieldName(), item.getString("UTF-8"));
				}
			}
		}
		catch (FileUploadBase.SizeLimitExceededException e) {
			throw new Exception("文件大小超出限制", e);
		}
		catch (FileUploadBase.FileSizeLimitExceededException e) {
			throw new Exception("文件大小超出限制", e);
		}
		catch (Exception e) {
			throw new Exception("上传文件失败", e);
		}
		return FileItems;
	}

	/**
	 * 通过URL上传，先下载保存本地，再上传
	 *
	 * @param request
	 * @param file
	 * @param saveName
	 * @return
	 * @throws IOException
	 */
	public String saveSingleFile(HttpServletRequest request, String url) throws IOException {
		String saveName = UUID.randomUUID().toString();
		saveName += ".xls";
		String floder = request.getSession().getServletContext().getRealPath("");
		FileUtils.copyInputStreamToFile(new URL(url).openStream(), new File(floder, saveName));
		File file = new File(floder, saveName);
		OssUtils.uploadFile(file, saveName,false);
		return saveName;
	}
	
}
